curl: Enable pipelining for HTTP/2
authorColin Walters <walters@verbum.org>
Wed, 5 Apr 2017 18:43:39 +0000 (14:43 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Wed, 12 Apr 2017 15:25:40 +0000 (15:25 +0000)
Testing a fetch of `fedora-atomic/.../docker-host` from
an nginx instance over `https://127.0.0.1` using Fedora 25
versions.  Average over 3 runs:

Before: ~24.6 seconds
After: ~19 seconds

Speedup: ~30%

Closes: https://github.com/ostreedev/ostree/issues/778
Closes: #780
Approved by: jlebon

src/libostree/ostree-fetcher-curl.c

index be0e4b416a4b1d28bd832fa5fc3fc95e53ca5a1f..829f44474d803951c5ef67868c039fa9128204d2 100644 (file)
 #define CURL_AT_LEAST_VERSION(x,y,z) (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
 #endif
 
+/* Cargo culted from https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */
+#ifndef CURLPIPE_MULTIPLEX
+/* This little trick will just make sure that we don't enable pipelining for
+   libcurls old enough to not have this symbol. It is _not_ defined to zero in
+   a recent libcurl header. */
+#define CURLPIPE_MULTIPLEX 0
+#endif
+
 #include "ostree-fetcher.h"
 #include "ostree-fetcher-util.h"
 #include "ostree-enumtypes.h"
@@ -219,6 +227,12 @@ _ostree_fetcher_init (OstreeFetcher *self)
 #if CURL_AT_LEAST_VERSION(7, 30, 0)
   /* Let's do something reasonable here. */
   curl_multi_setopt (self->multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 8);
+#endif
+  /* This version mirrors the version at which we're enabling HTTP2 support.
+   * See also https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c
+   */
+#if CURL_AT_LEAST_VERSION(7, 51, 0)
+  curl_multi_setopt (self->multi, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
 #endif
 }
 
@@ -764,6 +778,11 @@ initiate_next_curl_request (FetcherRequest *req,
    */
 #if CURL_AT_LEAST_VERSION(7, 51, 0)
   curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
+#endif
+  /* https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */
+#if (CURLPIPE_MULTIPLEX > 0)
+  /* wait for pipe connection to confirm */
+  curl_easy_setopt (req->easy, CURLOPT_PIPEWAIT, 1L);
 #endif
   curl_easy_setopt (req->easy, CURLOPT_WRITEFUNCTION, write_cb);
   if (g_getenv ("OSTREE_DEBUG_HTTP"))